package com.cardmanager.pro.executor;

import java.math.BigDecimal;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.cardmanager.pro.business.ConsumeTaskPOJOBusiness;
import com.cardmanager.pro.business.CreditCardAccountBusiness;
import com.cardmanager.pro.business.RepaymentTaskPOJOBusiness;
import com.cardmanager.pro.pojo.ConsumeTaskPOJO;
import com.cardmanager.pro.pojo.RepaymentTaskPOJO;
import com.cardmanager.pro.util.CardConstss;
import com.cardmanager.pro.util.RestTemplateUtil;

import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.ExceptionUtil;
import net.sf.json.JSONObject;

@Component
@Scope("prototype")
public class ThreadConsumeExecutor extends BaseExecutor implements Runnable {

	private final Logger LOG = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private ConsumeTaskPOJOBusiness consumeTaskPOJOBusiness;
	
	@Autowired
	private RepaymentTaskPOJOBusiness repaymentTaskPOJOBusiness;
	
	@Autowired
	private CreditCardAccountBusiness creditCardAccountBusiness;
	
	@Autowired
	private RestTemplateUtil util;
	
//	@Autowired
//	private CreditCardAccountHistoryBusiness creditCardAccountHistoryBusiness;
	
	private ConsumeTaskPOJO consumeTaskPOJO;
	
	
	@Override
	public void run() {
		boolean isTrue = true;
		while(isTrue){
			if(isTrue){
				String userId = consumeTaskPOJO.getUserId();
				String realAmount = consumeTaskPOJO.getRealAmount().toString();
				String amount = consumeTaskPOJO.getAmount().toString();
				String creditCardNumber = consumeTaskPOJO.getCreditCardNumber();
				String orderCode = consumeTaskPOJO.getConsumeTaskId();
				String description = consumeTaskPOJO.getDescription();
				String serviceCharge = consumeTaskPOJO.getServiceCharge().toString();
				String consumeTaskId = consumeTaskPOJO.getConsumeTaskId();
				String channelTag = consumeTaskPOJO.getChannelTag();
				String version = consumeTaskPOJO.getVersion();
				consumeTaskPOJO.setAmount(consumeTaskPOJO.getAmount().setScale(2, BigDecimal.ROUND_HALF_UP));
				String rate = repaymentTaskPOJOBusiness.findByRepaymentTaskId(consumeTaskPOJO.getRepaymentTaskId()).getRate().toString();
				
				if(!"2".equals(consumeTaskId.substring(consumeTaskId.length()-1))){
					ConsumeTaskPOJO consumeTaskPOJO2 = consumeTaskPOJOBusiness.findByConsumeTaskId(consumeTaskId.substring(0, consumeTaskId.length()-1)+"2");
					if(consumeTaskPOJO2 != null && consumeTaskPOJO2.getOrderStatus().intValue() != 1 ){
						consumeTaskPOJOBusiness.updateTaskStatus4AndReturnMessageByRepaymentTaskId(consumeTaskPOJO.getRepaymentTaskId(),"还款任务中首笔消费失败,无法继续执行该笔任务");
						this.updateConsumeService(consumeTaskPOJO2.getConsumeTaskId(),consumeTaskPOJO.getRepaymentTaskId());
						isTrue = false;
						break;
					}
				}
				
				consumeTaskPOJO.setOrderCode(orderCode);
				consumeTaskPOJOBusiness.save(consumeTaskPOJO);

				JSONObject resultJSONObject;
				try {
					resultJSONObject = addCreditCardOrder(userId,rate, "10", amount, realAmount, creditCardNumber,channelTag, orderCode, serviceCharge, description, "");
				} catch (RuntimeException e) {
					e.printStackTrace();LOG.error(ExceptionUtil.errInfo(e));
					this.errorDealWith(e, consumeTaskId);
					isTrue = false;
					break;
				}
				
				if(!CommonConstants.SUCCESS.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))){
					LOG.error("=============="+orderCode+"==============消费任务生成订单失败:原因:"+(resultJSONObject.containsKey(CommonConstants.RESP_MESSAGE)?resultJSONObject.getString(CommonConstants.RESP_MESSAGE):"生成订单失败"));
					this.failDealWith(resultJSONObject, consumeTaskId, "原因:生成订单失败");
					isTrue = false;
					break;
				}
				
				try {
					resultJSONObject = getUserInfo(userId);
				} catch (RuntimeException e) {
					e.printStackTrace();LOG.error(ExceptionUtil.errInfo(e));
					this.errorDealWith(e, consumeTaskId);
					isTrue = false;
					break;
				}
				
				if(!CommonConstants.SUCCESS.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))){
					LOG.error("=============="+orderCode+"==============消费任务获取用户信息失败:原因:"+(resultJSONObject.containsKey(CommonConstants.RESP_MESSAGE)?resultJSONObject.getString(CommonConstants.RESP_MESSAGE):"获取用户信息失败"));
					this.failDealWith(resultJSONObject, consumeTaskId, "原因:获取信息失败!");
					isTrue = false;
					break;
				}
				
				resultJSONObject = resultJSONObject.getJSONObject(CommonConstants.RESULT);
				String brandcode = resultJSONObject.getString("brandId");
				
				String extra = "0";
				
				try {
					resultJSONObject = paymentTopupRequest(realAmount, orderCode, description, userId, brandcode, "0", channelTag,extra);
					LOG.info("==============="+orderCode+"==============支付结果:" + resultJSONObject);
				} catch (Exception e) {
					e.printStackTrace();
					ExceptionUtil.errInfo(e);
					consumeTaskPOJO.setErrorMessage(e != null?ExceptionUtil.errInfo(e).substring(0, 250):"无错误信息");
					consumeTaskPOJO.setTaskStatus(1);
					consumeTaskPOJO.setOrderStatus(4);
					consumeTaskPOJO.setReturnMessage("等待银行扣款,请稍后!");
					ConsumeTaskPOJO findByConsumeTaskId = consumeTaskPOJOBusiness.findByConsumeTaskId(consumeTaskId);
					if (findByConsumeTaskId.getOrderStatus() == 1) {
						consumeTaskPOJO.setOrderStatus(1);
						consumeTaskPOJO.setReturnMessage("消费成功!");
					}
					consumeTaskPOJOBusiness.save(consumeTaskPOJO);
					isTrue = false;
					break;
				}
				
				if(!CommonConstants.SUCCESS.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))){
					if(CardConstss.WAIT_NOTIFY.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))) {
						consumeTaskPOJO.setTaskStatus(1);
						consumeTaskPOJO.setOrderStatus(4);
						consumeTaskPOJO.setReturnMessage("等待银行扣款,请稍后!");
						ConsumeTaskPOJO findByConsumeTaskId = consumeTaskPOJOBusiness.findByConsumeTaskId(consumeTaskId);
						if (findByConsumeTaskId.getOrderStatus() == 1) {
							consumeTaskPOJO.setOrderStatus(1);
							consumeTaskPOJO.setReturnMessage("消费成功!");
						}
						consumeTaskPOJOBusiness.save(consumeTaskPOJO);
					}else {
						LOG.error("=============="+orderCode+"==============消费任务支付失败:原因:"+(resultJSONObject.containsKey(CommonConstants.RESP_MESSAGE)?resultJSONObject.getString(CommonConstants.RESP_MESSAGE):"支付失败"));
						this.failDealWith(resultJSONObject, consumeTaskId, "原因:支付失败!");
					}
					isTrue = false;
					break;
				}
				consumeTaskPOJO.setTaskStatus(1);
				consumeTaskPOJO.setOrderStatus(1);
				consumeTaskPOJO.setReturnMessage("消费成功!");
				consumeTaskPOJOBusiness.save(consumeTaskPOJO);
					synchronized (creditCardAccountBusiness) {
						creditCardAccountBusiness.updateCreditCardAccountAndVersion(userId, creditCardNumber, consumeTaskPOJO.getConsumeTaskId(), 0, consumeTaskPOJO.getAmount(), description,consumeTaskPOJO.getVersion());
					}
				isTrue = false;
				break;
			}
		}
	}
	
	private void returnServiceCharge(){
		RepaymentTaskPOJO repaymentTaskPOJO = repaymentTaskPOJOBusiness.findByRepaymentTaskId(consumeTaskPOJO.getRepaymentTaskId());
		BigDecimal consumeReturnServiceCharge = consumeTaskPOJO.getAmount().multiply(repaymentTaskPOJO.getRate());
		repaymentTaskPOJO.setReturnServiceCharge(repaymentTaskPOJO.getReturnServiceCharge().add(consumeReturnServiceCharge).setScale(2, BigDecimal.ROUND_DOWN));
		repaymentTaskPOJO = repaymentTaskPOJOBusiness.save(repaymentTaskPOJO);
		synchronized (creditCardAccountBusiness) {
			creditCardAccountBusiness.updateCreditCardAccountAndVersion(repaymentTaskPOJO.getUserId(), repaymentTaskPOJO.getCreditCardNumber(), consumeTaskPOJO.getConsumeTaskId(),5, consumeReturnServiceCharge, "消费失败退还手续费",repaymentTaskPOJO.getVersion());
		}
	}
	
	
	private void updateConsumeService(String consumeTaskId,String repaymentTaskId){
		ConsumeTaskPOJO consumeTaskPOJO = consumeTaskPOJOBusiness.findByConsumeTaskId(consumeTaskId);
		RepaymentTaskPOJO repaymentTaskPOJO = repaymentTaskPOJOBusiness.findByRepaymentTaskId(repaymentTaskId);
		repaymentTaskPOJO.setTotalServiceCharge(BigDecimal.ZERO);
		repaymentTaskPOJO = repaymentTaskPOJOBusiness.save(repaymentTaskPOJO);
		consumeTaskPOJO.setServiceCharge(BigDecimal.ZERO);
		consumeTaskPOJO = consumeTaskPOJOBusiness.save(consumeTaskPOJO);
	}
	
	private void errorDealWith(Exception e,String consumeTaskId){
		consumeTaskPOJO.setErrorMessage(e != null?ExceptionUtil.errInfo(e).substring(0, 250):"无错误信息");
		consumeTaskPOJO.setTaskStatus(4);
		consumeTaskPOJO.setRealAmount(BigDecimal.ZERO);
		consumeTaskPOJO.setReturnMessage("消费失败!");
		consumeTaskPOJOBusiness.save(consumeTaskPOJO);
		if("2".equals(consumeTaskId.substring(consumeTaskId.length()-1))){
			consumeTaskPOJOBusiness.updateTaskStatus4AndReturnMessageByRepaymentTaskId(consumeTaskPOJO.getRepaymentTaskId(),"还款任务中首笔消费失败,无法继续执行该笔任务");
			this.updateConsumeService(consumeTaskId,consumeTaskPOJO.getRepaymentTaskId());
		}else{
			this.returnServiceCharge();
		}
		util.pushMessage(consumeTaskPOJO.getUserId(),"您有一笔金额为:"+consumeTaskPOJO.getAmount()+"的消费任务失败,可能会影响您的还款金额,请合理分配资金,避免信用卡逾期!");
	}
	
	private void failDealWith(JSONObject resultJSONObject,String consumeTaskId,String message){
		consumeTaskPOJO.setErrorMessage(resultJSONObject!=null&&resultJSONObject.containsKey(CommonConstants.RESP_MESSAGE)?resultJSONObject.getString(CommonConstants.RESP_MESSAGE):message);
		consumeTaskPOJO.setTaskStatus(2);
		consumeTaskPOJO.setRealAmount(BigDecimal.ZERO);
		consumeTaskPOJO.setReturnMessage(resultJSONObject.containsKey(CommonConstants.RESP_MESSAGE)?resultJSONObject.getString(CommonConstants.RESP_MESSAGE).replaceAll("[0-9]", "").replaceAll("[\\[|\\]|\\.|\\:]", "").replaceAll("[A-Za-z]", ""):message);
		consumeTaskPOJOBusiness.save(consumeTaskPOJO);
		if("2".equals(consumeTaskId.substring(consumeTaskId.length()-1))){
			consumeTaskPOJOBusiness.updateTaskStatus4AndReturnMessageByRepaymentTaskId(consumeTaskPOJO.getRepaymentTaskId(),"还款任务中首笔消费失败,无法继续执行该笔任务");
			this.updateConsumeService(consumeTaskId,consumeTaskPOJO.getRepaymentTaskId());
		}else{
			this.returnServiceCharge();
		}
		util.pushMessage(consumeTaskPOJO.getUserId(),"您有一笔金额为:"+consumeTaskPOJO.getAmount()+"的消费任务失败,可能会影响您的还款金额,请合理分配资金,避免信用卡逾期!");
	}
	

	public ConsumeTaskPOJO getConsumeTaskPOJO() {
		return consumeTaskPOJO;
	}

	public void setConsumeTaskPOJO(ConsumeTaskPOJO consumeTaskPOJO) {
		this.consumeTaskPOJO = consumeTaskPOJO;
	}
}
